<?php
 
class EstadoBusqueda extends PseudoEnum {
    const NO_REALIZADA = 0;
    const FALLIDA = 1;
    const EXITOSA = 2;
}

/**
 * Description of MatriculaAcademica
 *
 * @author JeyDotC
 * 
 * @export Modules
 * 
 * @export-metadata RequiredRoles:ROLE_STUDENT
 */
class MatriculaAcademica extends Module {

    /**
     *
     * @var academicRegistration
     */
    private $academicRegistration;
    private $cursos = array();
    private $filtros = array();
    private $estadoBusqueda;
    private $matricula = array();
    private $isInPruebaAcademica = false;

    /**
     *
     * @var Session
     */
    private $sesion;

    protected function onModuleReady() {
        $this->academicRegistration = $this->model->academicRegistration;
        $this->estadoBusqueda = EstadoBusqueda::NO_REALIZADA;
        $this->sesion = $this->request->getSession();
        $this->matricula = $this->cargarMatricula();
    }

    public function index() {

        $this->assign("Matricula", $this->matricula);
        $this->assign("searchAction", $this->route->action("buscarCursos"));
        $this->assign("urlRemover", $this->route->action("removerCurso"));
        $this->assign("urlMatricular", $this->route->action("guardarMatricula"));
        $this->assign("isInPruebaAcademica", $this->isInPruebaAcademica);

        $this->display("index");
    }

    public function buscarCursos() {

        $this->filtrarCursos();

        $this->assign("estadoBusqueda", $this->estadoBusqueda);
        $this->assign("filtros", $this->filtros);
        $this->assign("CursosHabilitados", $this->cursos);
        $this->assign("searchAction", $this->route->action("buscarCursos"));
        $this->assign("urlVolver", $this->route->action("index"));
        $this->assign("urlAddCurso", $this->route->action("agregarCurso"));

        $this->display("buscarCursos");
    }

    public function agregarCurso() {
        if ($this->request->submitted()) {
            Loader::using("models::entities::CursoPk");

            $pk = $this->request->post("CursoPk");

            $cursoPk = new CursoPk();
            $cursoPk->setCodigoMateria($pk["CodigoMateria"]);
            $cursoPk->setCodigoPlan($pk["CodigoPlan"]);
            $cursoPk->setGrupo($pk["Grupo"]);
            $cursoPk->setSemestre($pk["Semestre"]);
            $cursoPk->setPerdiodoAcademico(PeriodoAcademico::newInstance($pk["Ano"], $pk["Periodo"]));

            /* @var $curso Cursos */
            $curso = $this->model->courses->GetById($cursoPk);

            if ($curso->getCursoPk() != null) {
                $this->getPlexus()->doGuardarCurso($this, $curso);
            } else {
                $this->addMessage(new Message("El curso {$pk['CodigoMateria']} del grupo {$pk['Grupo']} No existe para este periodo.", "404 Curso no encontrado", Message::ERROR));
            }
        }

        $this->index();
    }

    public function removerCurso() {
        if ($this->request->submitted()) {
            Loader::using("models::entities::CursoPk");

            $pk = $this->request->post("CursoPk");

            $cursoPk = new CursoPk();
            $cursoPk->setCodigoMateria($pk["CodigoMateria"]);
            $cursoPk->setCodigoPlan($pk["CodigoPlan"]);
            $cursoPk->setGrupo($pk["Grupo"]);
            $cursoPk->setSemestre($pk["Semestre"]);
            $cursoPk->setPerdiodoAcademico(PeriodoAcademico::newInstance($pk["Ano"], $pk["Periodo"]));

            $this->getPlexus()->doQuitarCurso($this, $cursoPk);
            //$this->addMessage(new Message("Curso retirado con &eacute;xito", "", Message::SUCCESS));
        }

        $this->index();
    }

    public function guardarMatricula() {
        if ($this->request->submitted()) {
            $matricula = $this->getMatricula();
            $estudiante = $this->model->students->GetById($this->currentUser->getName());
            foreach ($matricula as /* @var $curso Cursos */$curso) {
                $cursoMatriculado = new CursosMatriculados();

                $cursoMatriculadoPk = new CursosMatriculadosPk();
                $cursoMatriculadoPk->setCodigoEstudiante($this->currentUser->getName());
                $cursoMatriculadoPk->setCursoPk($curso->getCursoPk());

                $cursoMatriculado->setCursoMatriculadoPk($cursoMatriculadoPk);
                $cursoMatriculado->setFechaMatricula(MicrosoftDateFormatter::toJSON(date("d/m/Y")));

                /* @var $result ServiceResponse */
                $result = $this->model->academicRegistration->MatricularCurso($cursoMatriculado);
                $type = $result->getSuccess() ? Message::SUCCESS : Message::ERROR;
                $this->addMessage(new Message($result->getMessage(), "", $type));
            }

            $this->sesion->remove("Acaweb.Matricula.CursosAgregados");
            $this->display();
        } else {
            $this->index();
        }
    }

    private function cargarMatricula() {
        $matricula = array();

        if ($this->sesion->has("Acaweb.Matricula.CursosAgregados")) {
            Loader::using("models::entities::Cursos");
            $matricula = unserialize($this->sesion->get("Acaweb.Matricula.CursosAgregados"));
        } else {
            Loader::using("models::entities::Cursos");
            $matricula = $this->academicRegistration->GetPreMatricula();
        }

        return $matricula;
    }

    private function getPlexus() {
        Loader::using("BusinessLogic::Acaweb::MatriculaAcademica::lib::constraints::*");
        return new Plexus(new PluginCollection(array(
                            "CreditosInsuficientes",
                            "ConflictoDeHorarios",
                            "EnPrematriculaYPerdidaAnteriormente",
                            "AproboMenosDel40PorCientoPeriodoAnterior",
                            "CursoNoAutorizado",
                        )));
    }

    private function filtrarCursos() {
        if ($this->request->submitted()) {
            Loader::using("ext::libs::AcawebUtils");
            Loader::using("models::entities::PeriodoAcademico");
            require_once 'lib/coursesFilters/CourseFilter.php';

            $cursosHabilitados = $this->model->courses->GetHabilitados(AcawebUtils::GetPeriodoAcademicoMatriculas());

            $this->filtros = $this->request->post("CoursesFilters");
            $filters = new CourseFilterLoader();

            foreach ($cursosHabilitados as $curso) {
                $score = 0;
                foreach ($this->filtros as $filtro => $parametro) {
                    $score += $filters->load($filtro)->filter($curso, $parametro);
                }

                if (count($this->filtros) == 0 || $score / count($this->filtros) >= SearchScore::MEDIUM) {
                    $this->cursos[] = $curso;
                }
            }

            if (count($this->cursos) > 0) {
                $this->estadoBusqueda = EstadoBusqueda::EXITOSA;
            } else {
                $this->estadoBusqueda = EstadoBusqueda::FALLIDA;
            }
        }
    }

    /**
     *
     * @param Cursos $curso 
     */
    public function guardarCurso(Cursos $curso) {
        $this->matricula[] = $curso;
        $this->sesion->put("Acaweb.Matricula.CursosAgregados", serialize($this->matricula));
    }

    public function quitarCurso(CursoPk $cursoPk) {
        foreach ($this->matricula as $k => /* @var $curso Cursos */ $curso) {
            if ($curso->getCursoPk()->toString() == $cursoPk->toString()) {
                unset($this->matricula[$k]);
            }
        }
        $this->sesion->put("Acaweb.Matricula.CursosAgregados", serialize($this->matricula));
    }

    /**
     *
     * @return Array
     */
    public function getMatricula() {
        return $this->matricula;
    }

    public function getIsInPruebaAcademica() {
        return $this->isInPruebaAcademica;
    }

    public function setIsInPruebaAcademica($isInPruebaAcademica) {
        $this->isInPruebaAcademica = $isInPruebaAcademica;
    }

}

?>
